/******************************************************************************
 *
 *  Copyright (C) 2010-2014 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/
/******************************************************************************
 *
 *  The original Work has been changed by NXP Semiconductors.
 *
 *  Copyright (C) 2015 NXP Semiconductors
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/


/******************************************************************************
 *
 *  This file contains functions that NCI vendor specific interface with the
 *  NFCC. On the receive side, it routes events to the appropriate handler
 *  (callback). On the transmit side, it manages the command transmission.
 *
 ******************************************************************************/
#include <string.h>
#include "gki.h"
#include "nfc_target.h"

#if (NFC_INCLUDED == TRUE)
#include "nfc_int.h"

/****************************************************************************
** Declarations
****************************************************************************/



/*******************************************************************************
**
** Function         NFC_RegVSCback
**
** Description      This function is called to register or de-register a callback
**                  function to receive Proprietary NCI response and notification
**                  events.
**                  The maximum number of callback functions allowed is NFC_NUM_VS_CBACKS
**
** Returns          tNFC_STATUS
**
*******************************************************************************/
tNFC_STATUS NFC_RegVSCback (BOOLEAN          is_register,
                            tNFC_VS_CBACK   *p_cback)
{
    tNFC_STATUS status = NFC_STATUS_FAILED;
    int i;

    if (is_register)
    {
        for (i = 0; i < NFC_NUM_VS_CBACKS; i++)
        {
            /* find an empty spot to hold the callback function */
            if (nfc_cb.p_vs_cb[i] == NULL)
            {
                nfc_cb.p_vs_cb[i]  = p_cback;
                status             = NFC_STATUS_OK;
                break;
            }
        }
    }
    else
    {
        for (i = 0; i < NFC_NUM_VS_CBACKS; i++)
        {
            /* find the callback to de-register */
            if (nfc_cb.p_vs_cb[i] == p_cback)
            {
                nfc_cb.p_vs_cb[i]  = NULL;
                status             = NFC_STATUS_OK;
                break;
            }
        }
    }
    return status;
}


/*******************************************************************************
**
** Function         NFC_SendVsCommand
**
** Description      This function is called to send the given vendor specific
**                  command to NFCC. The response from NFCC is reported to the
**                  given tNFC_VS_CBACK as (oid).
**
** Parameters       oid - The opcode of the VS command.
**                  p_data - The parameters for the VS command
**
** Returns          tNFC_STATUS
**
*******************************************************************************/
tNFC_STATUS NFC_SendVsCommand (UINT8          oid,
                               BT_HDR        *p_data,
                               tNFC_VS_CBACK *p_cback)
{
    tNFC_STATUS     status = NFC_STATUS_OK;
    UINT8           *pp;

    /* Allow VSC with 0-length payload */
    if (p_data == NULL)
    {
        p_data = NCI_GET_CMD_BUF (0);
        if (p_data)
        {
            p_data->offset  = NCI_VSC_MSG_HDR_SIZE;
            p_data->len     = 0;
        }
    }

    /* Validate parameters */
    if ((p_data == NULL) || (p_data->offset < NCI_VSC_MSG_HDR_SIZE) || (p_data->len > NCI_MAX_VSC_SIZE))
    {
        NFC_TRACE_ERROR1 ("buffer offset must be >= %d", NCI_VSC_MSG_HDR_SIZE);
        if (p_data)
            GKI_freebuf (p_data);
        return NFC_STATUS_INVALID_PARAM;
    }

    p_data->event           = BT_EVT_TO_NFC_NCI;
    p_data->layer_specific  = NFC_WAIT_RSP_VSC;
    /* save the callback function in the BT_HDR, to receive the response */
    ((tNFC_NCI_VS_MSG *) p_data)->p_cback = p_cback;

    p_data->offset -= NCI_MSG_HDR_SIZE;
    pp              = (UINT8 *) (p_data + 1) + p_data->offset;
    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_PROP);
    NCI_MSG_BLD_HDR1 (pp, oid);
    *pp             = (UINT8) p_data->len;
    p_data->len    += NCI_MSG_HDR_SIZE;
    nfc_ncif_check_cmd_queue (p_data);
    return status;
}
#if(NXP_EXTNS == TRUE)
/*******************************************************************************
**
** Function         NFC_SendNxpNciCommand
**
** Description      This function is called to send the given nxp specific
**                  command to NFCC. The response from NFCC is reported to the
**                  given tNFC_VS_CBACK.
**
** Parameters       p_data - The command buffer
**
** Returns          tNFC_STATUS
**
*******************************************************************************/
tNFC_STATUS NFC_SendNxpNciCommand (BT_HDR        *p_data,
                               tNFC_VS_CBACK *p_cback)
{
    tNFC_STATUS     status = NFC_STATUS_OK;
    UINT8           *pp;

    /* Validate parameters */
    if ((p_data == NULL) || (p_data->len > NCI_MAX_VSC_SIZE))
    {
        NFC_TRACE_ERROR1 ("buffer offset must be >= %d", NCI_VSC_MSG_HDR_SIZE);
        if (p_data)
            GKI_freebuf (p_data);
        return NFC_STATUS_INVALID_PARAM;
    }

    p_data->event           = BT_EVT_TO_NFC_NCI;
    p_data->layer_specific  = NFC_WAIT_RSP_NXP;
    /* save the callback function in the BT_HDR, to receive the response */
    ((tNFC_NCI_VS_MSG *) p_data)->p_cback = p_cback;
    pp              = (UINT8 *) (p_data + 1) + p_data->offset;

    nfc_ncif_check_cmd_queue (p_data);
    return status;
}
#endif

#endif /* NFC_INCLUDED == TRUE */
